from functools import wraps

from flask import g, redirect, url_for, request, flash

from models.users import User


def login_required(func):
    """装饰器功能：只允许已登录用户访问"""

    @wraps(func)
    def inner(*args, **kwargs):

        if g.username == 'anonymous':
            # 提示用户请先登录
            flash('请先登录')
            # 用户未认证,重定向到登录界面,并以查询字符串的形式保存跳转前的端点名
            return redirect(url_for('users.login', next=request.endpoint))
        else:
            return func(*args, **kwargs)

    return inner


def permission_required(permission):
    def outer(func):
        @wraps(func)
        def inner(*args, **kwargs):
            user = User.query.filter_by(username=g.username).first()
            if user.role.has_permission(permission):
                return func(*args, **kwargs)
            else:
                return redirect(
                    url_for('errors.permission_error', missing_permission=permission, next=request.endpoint))

        return inner

    return outer


def single_instance(cls):
    """单例模式装饰器"""
    _instance = None

    @wraps(cls)
    def inner(*args, **kwargs):
        nonlocal _instance
        _instance = cls(*args, **kwargs) if not _instance else _instance
        return _instance

    return inner


# @single_instance
class A(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(A, '_instance'):
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

    pass


if __name__ == '__main__':
    a1 = A()
    a2 = A()
    print(a1)
    print(a2)
    print(A)
